package com.xmy.cultivate.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xmy.cultivate.entity.*;
import com.xmy.cultivate.enums.RecruitStatusEnum;
import com.xmy.cultivate.mapper.GradeAutoSetMapper;
import com.xmy.cultivate.mapper.RecordCourseMapper;
import com.xmy.cultivate.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xmy.cultivate.util.CommonUtil;
import com.xmy.cultivate.util.IdWorker;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 批量添加班级设置 服务实现类
 * </p>
 *
 * @author hpiggy
 * @since 2024-12-10
 */
@Service
public class GradeAutoSetServiceImpl extends ServiceImpl<GradeAutoSetMapper, GradeAutoSet> implements IGradeAutoSetService {

    @Autowired
    ISchoolQuarterService iSchoolQuarterService;
    @Autowired
    private RecordCourseMapper recordCourseMapper;

    @Autowired
    IGradeService iGradeService;

    @Autowired
    ICourseService iCourseService;

    @Autowired
    IClassRoomService iClassRoomService;

    @Autowired
    IStaffService iStaffService;

    @Autowired
    IDictService iDictService;

    @Autowired
    ICourseSchedulingAlwaysService iCourseSchedulingAlwaysService;

    @Autowired
    IQuarterService iQuarterService;

    @Autowired
    ISubjectsService iSubjectsService;

    @Autowired
    IdWorker idWorker;

    /**
     *
     * @param yearPart
     * @param quarterNum
     * @param schoolId
     * @param yearClassId
     * @param type 1上个学期有上过课的才创建，2为没有上过课的校区也创建
     */
    @Async("onlineAsync")
    @Override
    public void createGradeAuto(Integer yearPart, Integer quarterNum, Long schoolId,String yearClassId,Integer type) {

        IPage<Map<String, Object>> iPage = new Page<>(1, 100);

        QueryWrapper<SchoolQuarter> qw = new QueryWrapper<>();
        qw.eq("year_part",yearPart);
        qw.eq("quarter_num",quarterNum);
        qw.eq("is_alone",1);//独立场地
        qw.eq(schoolId != null,"school_id",schoolId);//
        List<SchoolQuarter> schoolList = iSchoolQuarterService.list(qw);

        QueryWrapper<GradeAutoSet> gradeAutoSetQueryWrapper = new QueryWrapper<>();
        gradeAutoSetQueryWrapper.eq("year_part",yearPart);
        gradeAutoSetQueryWrapper.eq("quarter_num",quarterNum);
        //gradeAutoSetQueryWrapper.eq("lesson_type",3);

        List<Subjects> subjectsList = iSubjectsService.list(new QueryWrapper<Subjects>().eq("type",1).orderByAsc("sort"));

        List<GradeAutoSet> gradeAutoSets = this.list(gradeAutoSetQueryWrapper);
        for (GradeAutoSet gradeAutoSet : gradeAutoSets) {
            //有独立地址的校区
            for (SchoolQuarter schoolQuarter : schoolList) {
                for (Subjects subjects : subjectsList) {
                    if (subjects.getId().equals(1L) && !gradeAutoSet.getLessonType().equals(2)){
                        continue;
                    }else if ((subjects.getId().equals(2L) || subjects.getId().equals(3L)) && !gradeAutoSet.getLessonType().equals(3)){
                        continue;
                    }
                    Long schoolIdQuarter = schoolQuarter.getSchoolId();

                    QueryWrapper<Course> courseQw = new QueryWrapper<>();
                    courseQw.eq("a.status", 1);
                    courseQw.eq("a.deleted", 0);
                    courseQw.and(i -> i.eq("a.opening_school_type", 1).or().inSql("a.id", "select for_id from appoint_school where type=1 and school_id =" + schoolIdQuarter));
                    courseQw.in("a.subjects_id", subjects.getId());
                    courseQw.in("a.quarter_num", schoolQuarter.getQuarterNum());
                    courseQw.eq("lesson_type", gradeAutoSet.getLessonType());
                    iCourseService.checkCourse(iPage, courseQw, schoolIdQuarter);
                    if (iPage.getTotal()>0){
                        Course course = (Course)iPage.getRecords().get(0);

                        //教室
                        QueryWrapper<ClassRoom> classRoomQueryWrapper =  new QueryWrapper<>();
                        classRoomQueryWrapper.eq("deleted",0);
                        classRoomQueryWrapper.eq("lesson_type",course.getLessonType());
                        classRoomQueryWrapper.and(wrapper->wrapper.in("school_id",schoolIdQuarter).or().eq("school_id",0));
                        classRoomQueryWrapper.orderByDesc("id");
                        classRoomQueryWrapper.last("limit 1");
                        ClassRoom classRoom = iClassRoomService.getOne(classRoomQueryWrapper);
                        if (classRoom==null){
                            System.out.println(schoolIdQuarter+"：教室不存在，科目："+subjects.getId());
                            continue;
                        }

                        //老师
                        String status = "1";
                        QueryWrapper<Staff> staffQueryWrapper = new QueryWrapper<>();
                        staffQueryWrapper.eq("is_teacher", 1);
                        staffQueryWrapper.eq(StringUtils.isNotBlank(status), "status", status);
                        staffQueryWrapper.and(i -> i.eq("scope_class_mode", 1).or().inSql("id", "select for_id from appoint_school where type=4 and school_id in(" + schoolIdQuarter + ")"));
                        staffQueryWrapper.eq("deleted", 0);
                        staffQueryWrapper.last("limit 1");
                        Staff staff = iStaffService.getOne(staffQueryWrapper);
                        if (staff==null){
                            System.out.println(schoolIdQuarter+"：老师不存在，科目："+subjects.getId());
                            continue;
                        }

                        //是否假期
                        Integer isVacation = iDictService.getIsVacation(course.getQuarterNum());
                        Integer gradeSection = CommonUtil.getGradeSectionForYearClassId(course.getYearClassId().getKey());
                        LocalDate openDate = iCourseSchedulingAlwaysService.getStartDate(yearPart, course.getQuarterNum(), gradeSection, null);
                        LocalDate endDate = iCourseSchedulingAlwaysService.getEndDate(yearPart, course.getQuarterNum(), gradeSection, null);
                            /*QueryWrapper<Grade> gradeQueryWrapper = new QueryWrapper<>();
                            gradeQueryWrapper.eq("year_part",yearPart);
                            gradeQueryWrapper.eq("quarter_num",quarterNum);
                            gradeQueryWrapper.eq("school_id",schoolIdQuarter);
                            gradeQueryWrapper.eq("course_id",course.getCourseTypeId());*/
                        String weekDates;
                        String schedulingType;
                        if (isVacation.equals(1)){
                            weekDates = "A";
                            schedulingType = "A天";
                            //假期
                            this.createGrade(yearPart,quarterNum,schoolIdQuarter,course,gradeAutoSet,openDate,endDate,isVacation,classRoom,staff,subjects,weekDates,schedulingType);
                        }else {
                            //学期
                            if (gradeAutoSet.getWeekType().equals(1)){
                                //周内
                                schedulingType = "A类";
                                for (Integer i=1;i<=5;i++){
                                    weekDates = i.toString();
                                    this.createGrade(yearPart,quarterNum,schoolIdQuarter,course,gradeAutoSet,openDate,endDate,isVacation,classRoom,staff,subjects,weekDates,schedulingType);
                                }
                            }else {
                                //周末
                                schedulingType = "B类";
                                Integer[] arrayData = {0,6};
                                for (Integer i :arrayData){
                                    weekDates = i.toString();
                                    this.createGrade(yearPart,quarterNum,schoolIdQuarter,course,gradeAutoSet,openDate,endDate,isVacation,classRoom,staff,subjects,weekDates,schedulingType);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    public boolean createGrade(Integer yearPart,
                               Integer quarterNum,
                               Long schoolIdQuarter,
                               Course course,
                               GradeAutoSet gradeAutoSet,
                               LocalDate openDate,
                               LocalDate endDate,
                               Integer isVacation,
                               ClassRoom classRoom,
                               Staff staff,
                               Subjects subjects,
                               String weekDates,
                               String schedulingType){
        QueryWrapper<Grade> gradeQueryWrapper = new QueryWrapper<>();
        gradeQueryWrapper.eq("year_part",yearPart);
        gradeQueryWrapper.eq("quarter_num",quarterNum);
        gradeQueryWrapper.eq("week_dates",weekDates);
        gradeQueryWrapper.eq("scheduling_type",schedulingType);
        gradeQueryWrapper.eq("lesson_type",course.getLessonType());
        gradeQueryWrapper.eq("school_id",schoolIdQuarter);
        gradeQueryWrapper.eq("subjects_id",subjects.getId());
        gradeQueryWrapper.eq("time_start",gradeAutoSet.getTimeStart());
        gradeQueryWrapper.eq("time_end",gradeAutoSet.getTimeEnd());
        Long count = iGradeService.count(gradeQueryWrapper);
        if (count>0){
            return true;
        }

        String weekName = CommonUtil.getWeekForId(Integer.parseInt(weekDates));

        Grade grade = new Grade();
        grade.setId(idWorker.nextId());
        grade.setYearPart(yearPart);
        grade.setQuarterNum(quarterNum);
        grade.setSchoolId(schoolIdQuarter);
        grade.setCourseId(course.getId());
        grade.setCourseTypeId(course.getCourseTypeId());
        grade.setYearClassId(course.getYearClassId());
        grade.setLessonType(course.getLessonType());
        grade.setName(weekName + gradeAutoSet.getName());
        grade.setRecruitStatus(RecruitStatusEnum.OPEN);
        grade.setOpenDate(openDate);
        grade.setEndDate(endDate);
        grade.setTimeStart(gradeAutoSet.getTimeStart());//开始时间
        grade.setTimeEnd(gradeAutoSet.getTimeEnd());//结束时间
        grade.setIsVacation(isVacation);
        grade.setWeekDates(weekDates);//周几
        grade.setIsAutoScheduling(0);
        grade.setSchedulingType(schedulingType);//类型
        grade.setClassRoomId(classRoom.getId());
        grade.setTeacherId(staff.getId());
        grade.setTeacherName(staff.getName());
        grade.setSubjectsId(Long.valueOf(subjects.getId().toString()));
        grade.setIsScheduling(0);
        grade.setFullCount(0);
        grade.setStuDeductHour(0);
        grade.setTeaGainHour(0);
        grade.setCourseTypeId(1575859909042028546L);

        iGradeService.save(grade);
        return true;
    }


    /**
     *
     * @param yearPart
     * @param quarterNum
     * @param schoolId
     * @param yearClassId
     * @param type 1上个学期有上过课的才创建，2为没有上过课的校区也创建
     */
    @Async("onlineAsync")
    @Override
    public void createGradeAutoV2(Integer yearPart, Integer quarterNum, Long schoolId, String yearClassId, Integer type) {

        IPage<Map<String, Object>> iPage = new Page<>(1, 100);

        QueryWrapper<SchoolQuarter> qw = new QueryWrapper<>();
        qw.eq("year_part",yearPart);
        qw.eq("quarter_num",quarterNum);
        qw.eq("is_alone",1);//独立场地
        qw.eq(schoolId != null,"school_id",schoolId);//
        List<SchoolQuarter> schoolList = iSchoolQuarterService.list(qw);

        QueryWrapper<GradeAutoSet> gradeAutoSetQueryWrapper = new QueryWrapper<>();
        gradeAutoSetQueryWrapper.eq("year_part",yearPart);
        gradeAutoSetQueryWrapper.eq("quarter_num",quarterNum);
        //gradeAutoSetQueryWrapper.eq("lesson_type",3);

        // 获取当前日期
        LocalDate dateNow = LocalDate.now();
        // 获取当前日期是星期几
        DayOfWeek dayOfWeek = dateNow.getDayOfWeek();
        // 判断是周内还是周末
        if (dayOfWeek == DayOfWeek.SATURDAY || dayOfWeek == DayOfWeek.SUNDAY) {
            //当前时间周末
        } else {
            //周内
        }


        Quarter quarter = iQuarterService.getQuarterForYearAndNum(yearPart,quarterNum);

        //上个学期
        Quarter upQuarter = iQuarterService.getUpQuarter(yearPart,quarterNum,1);


        List<Subjects> subjectsList = iSubjectsService.list(new QueryWrapper<Subjects>().eq("type",1).orderByAsc("sort"));

        List<GradeAutoSet> gradeAutoSets = this.list(gradeAutoSetQueryWrapper);
        for (GradeAutoSet gradeAutoSet : gradeAutoSets) {
            //有独立地址的校区
            for (SchoolQuarter schoolQuarter : schoolList) {
                for (Subjects subjects : subjectsList) {
                    if (subjects.getId().equals(1L) && !gradeAutoSet.getLessonType().equals(2)){
                        continue;
                    }else if ((subjects.getId().equals(2L) || subjects.getId().equals(3L)) && !gradeAutoSet.getLessonType().equals(3)){
                        continue;
                    }

                    Long schoolIdQuarter = schoolQuarter.getSchoolId();
                    List<Long> schoolIdList = iSchoolQuarterService.getChilIdList(yearPart,quarterNum,schoolIdQuarter.toString());

                    //查看上个学期是否开了这个课
                    QueryWrapper<RecordCourse> recordCourseQueryWrapper = new QueryWrapper<>();
                    recordCourseQueryWrapper.eq("year_part",upQuarter.getYearPart());
                    recordCourseQueryWrapper.eq("quarter",upQuarter.getNum());
                    recordCourseQueryWrapper.eq("subjects_id",subjects.getId());
                    recordCourseQueryWrapper.in("school_id",schoolIdList);
                    Long count = recordCourseMapper.selectCount(recordCourseQueryWrapper);//查看这个校区是否开这个科目
                    if (count > 0 || schoolId != null || type == 2) {
                        QueryWrapper<Course> courseQw = new QueryWrapper<>();
                        courseQw.eq("a.status", 1);
                        courseQw.eq("a.deleted", 0);
                        courseQw.and(i -> i.eq("a.opening_school_type", 1).or().inSql("a.id", "select for_id from appoint_school where type=1 and school_id =" + schoolIdQuarter));
                        courseQw.in("a.subjects_id", subjects.getId());
                        courseQw.in("a.quarter_num", schoolQuarter.getQuarterNum());
                        courseQw.eq("lesson_type", gradeAutoSet.getLessonType());
                        iCourseService.checkCourse(iPage, courseQw, schoolIdQuarter);
                        if (iPage.getTotal()>0){
                            Course course = (Course)iPage.getRecords().get(0);

                            //教室
                            QueryWrapper<ClassRoom> classRoomQueryWrapper =  new QueryWrapper<>();
                            classRoomQueryWrapper.eq("deleted",0);
                            classRoomQueryWrapper.eq("lesson_type",course.getLessonType());
                            classRoomQueryWrapper.and(wrapper->wrapper.in("school_id",schoolIdQuarter).or().eq("school_id",0));
                            classRoomQueryWrapper.orderByDesc("id");
                            classRoomQueryWrapper.last("limit 1");
                            ClassRoom classRoom = iClassRoomService.getOne(classRoomQueryWrapper);
                            if (classRoom==null){
                                System.out.println(schoolIdQuarter+"：教室不存在，科目："+subjects.getId());
                                continue;
                            }

                            //老师
                            String status = "1";
                            QueryWrapper<Staff> staffQueryWrapper = new QueryWrapper<>();
                            staffQueryWrapper.eq("is_teacher", 1);
                            staffQueryWrapper.eq(StringUtils.isNotBlank(status), "status", status);
                            staffQueryWrapper.and(i -> i.eq("scope_class_mode", 1).or().inSql("id", "select for_id from appoint_school where type=4 and school_id in(" + schoolIdQuarter + ")"));
                            staffQueryWrapper.eq("deleted", 0);
                            staffQueryWrapper.last("limit 1");
                            Staff staff = iStaffService.getOne(staffQueryWrapper);
                            if (staff==null){
                                System.out.println(schoolIdQuarter+"：老师不存在，科目："+subjects.getId());
                                continue;
                            }

                            //是否假期
                            Integer isVacation = iDictService.getIsVacation(course.getQuarterNum());
                            Integer gradeSection = CommonUtil.getGradeSectionForYearClassId(course.getYearClassId().getKey());
                            LocalDate openDate = iCourseSchedulingAlwaysService.getStartDate(yearPart, course.getQuarterNum(), gradeSection, null);
                            LocalDate endDate = iCourseSchedulingAlwaysService.getEndDate(yearPart, course.getQuarterNum(), gradeSection, null);
                            /*QueryWrapper<Grade> gradeQueryWrapper = new QueryWrapper<>();
                            gradeQueryWrapper.eq("year_part",yearPart);
                            gradeQueryWrapper.eq("quarter_num",quarterNum);
                            gradeQueryWrapper.eq("school_id",schoolIdQuarter);
                            gradeQueryWrapper.eq("course_id",course.getCourseTypeId());*/

                            Grade grade = new Grade();
                            grade.setId(idWorker.nextId());
                            grade.setYearPart(yearPart);
                            grade.setQuarterNum(quarterNum);
                            grade.setSchoolId(schoolIdQuarter);
                            grade.setCourseId(course.getId());
                            grade.setCourseTypeId(course.getCourseTypeId());
                            grade.setYearClassId(course.getYearClassId());
                            grade.setLessonType(course.getLessonType());
                            grade.setName(gradeAutoSet.getName());
                            grade.setRecruitStatus(RecruitStatusEnum.OPEN);
                            grade.setOpenDate(openDate);
                            grade.setEndDate(endDate);
                            grade.setTimeStart(gradeAutoSet.getTimeStart());
                            grade.setTimeEnd(gradeAutoSet.getTimeEnd());
                            grade.setIsVacation(isVacation);
                            grade.setWeekDates("A");
                            grade.setIsAutoScheduling(0);
                            grade.setSchedulingType("A天");
                            grade.setClassRoomId(classRoom.getId());
                            grade.setTeacherId(staff.getId());
                            grade.setTeacherName(staff.getName());
                            grade.setSubjectsId(Long.valueOf(subjects.getId().toString()));
                            grade.setIsScheduling(0);
                            grade.setFullCount(0);
                            grade.setStuDeductHour(0);
                            grade.setTeaGainHour(0);
                            grade.setCourseTypeId(1575859909042028546L);

                            iGradeService.save(grade);
                        }
                    }
                }
            }
        }
    }
}
